package com.maxd.task;

import com.maxd.error.DescribeException;
import com.maxd.handler.pay.IPayHandler;
import com.maxd.model.PayRecord;
import com.maxd.respository.PayRecordRepository;
import com.maxd.service.selfWXPay.WxPayV3Service;
import com.maxd.utils.ApplicationContextUtils;
import com.maxd.utils.JsonUtils;
import com.wechat.pay.java.service.payments.model.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;

@Component
public class PayResultCheckTask {

    private static final Logger log = LoggerFactory.getLogger(PayResultCheckTask.class);
    @Autowired
    private PayRecordRepository payRecordRepository;

    @Autowired
    private WxPayV3Service wxPayV3Service;

    /**
     * 每2分钟执行1次
     */
    @Scheduled(cron = "0 */2 * * * ?")
    public void payResultCheck() {
        log.info("开始执行支付状态确认批处理");
        List<PayRecord> payRecords = payRecordRepository.queryWaitCheckList();
        log.info("查询到待确认的的支付流水记录数为:{}", payRecords.size());
        for (PayRecord payRecord : payRecords) {
            try {
                log.info("支付记录确认:{}", JsonUtils.toJsonString(payRecord));
                IPayHandler payHandler = getPayHandler(payRecord.getPayScene());
                // 如果超过30分钟状态还是0-初始化，直接取消
                if("0".equals(payRecord.getPayStatus())) {
                    log.info("支付状态为初始化，执行取消逻辑，支付流水号:{}，业务流水号:{}，支付场景:{}", payRecord.getPaySeq(), payRecord.getBusinessId(), payRecord.getPayScene());
                    payHandler.cancelHandler(payRecord);
                    payRecordRepository.updateStatus(payRecord.getPaySeq(), "3");
                } else {
                    // 支付中的状态，查询支付结果
                    Transaction transaction = wxPayV3Service.queryPayResult(payRecord.getPaySeq());
                    // 支付成功的情况
                    if(Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
                        log.info("查询支付结果为支付成功，执行支付成功后处理，支付流水号:{}", payRecord.getPaySeq());
                        // 支付成功回调
                        payHandler.callBackHandler(payRecord);
                        // 更新支付状态
                        payRecordRepository.updatePaySuccess(payRecord.getPaySeq(), transaction.getTransactionId());
                    } else {
                        // 未支付成功的情况
                        log.info("查询支付结果不为支付成功，取消订单处理", payRecord.getPaySeq());
                        payHandler.cancelHandler(payRecord);
                        try {
                            wxPayV3Service.closeOrder(payRecord.getPaySeq());
                        } catch (Exception e) {
                            log.info("关闭微信支付订单失败.", e);
                        }
                        payRecordRepository.updateStatus(payRecord.getPaySeq(), "3");
                    }
                }
            } catch (Exception e) {
                log.error("微信支付状态确认执行失败:" + payRecord.getPaySeq(), e);
            }
        }
    }

    private IPayHandler getPayHandler(String payScene) {
        Collection<IPayHandler> payHandlers = ApplicationContextUtils.getBeansOfType(IPayHandler.class);
        for (IPayHandler payHandler : payHandlers) {
            if(payHandler.getScene().equals(payScene)) {
                return payHandler;
            }
        }
        throw new DescribeException("获取不到支付场景对应的处理器", -1);
    }

}
